/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package plot;

import java.io.FileWriter;
import java.io.PrintWriter;
import world.Base;
import world.Enemy;
import world.Flag;
import world.Friend;
import world.Obstacle;
import world.Point;
import world.World;

/**
 *
 * @author dheath
 */
public class GNUPlot
{

    private String outputFile;
    private jgnuplot plotrunner;
    private boolean gnuplot;
    private boolean tofile;
    private String outputStr;
    private FileWriter fstream;
    private PrintWriter out;
    private World world;
    private double plotSpeed;
    
    // initialization
    public GNUPlot(World w, boolean gnuplot, boolean tofile, String filename, double plotSpeed)
    {
        outputStr = "";
        this.world = w;
        this.gnuplot = gnuplot;
        this.tofile = tofile;
        this.plotSpeed = plotSpeed;
        
        if (gnuplot)
        {
            plotrunner = new jgnuplot();
        }
        if (tofile)
        {
            this.outputFile = filename;
            try
            {
                // Create file 
                fstream = new FileWriter(this.outputFile);
                out = new PrintWriter(fstream);

            } catch (Exception e)
            {
                System.err.println("Error: " + e.getMessage());
            }
        }
        printHeaderData(this.outputFile);
        printWorld();
        //printFooterData();
    }
    
    public void closeConnection()
    {
        printFooterData();
        try
        {
            out.close();
        } catch (Exception e)
        {
            System.err.println("Error: " + e.getMessage());
        }
    }

    private void printHeaderData(String title)
    {
        double worldsize = Double.parseDouble(world.getConstants().get("worldsize"));

        String c1 = "set title \"" + title + "\"";
        String c2 = "set xrange [-" + (worldsize / 2) + ": " + (worldsize / 2) + "]";
        String c3 = "set yrange [-" + (worldsize / 2) + ": " + (worldsize / 2) + "]";
        String c4 = "unset key";
        String c5 = "set size square";
        output(c1);
        output(c2);
        output(c3);
        output(c4);
        output(c5);
        
        System.out.println("end printHeader");
    }

    public void output(String line)
    {
        if (gnuplot)
        {
            plotrunner.cmd(line);
        }
        if (tofile)
        {
            try
            {
                out.println(line);
            } catch (Exception e)
            {
                System.err.println("Error: " + e.getMessage());
            }
        }
    }

    private void printWorld()
    {
        output("unset arrow");
        for (Obstacle ob : world.getObstacles())
        {
            output("set arrow from " + ob.getBLPoint().getX() + ", " + ob.getBLPoint().getY() + " to " +
                    ob.getBRPoint().getX() + ", " + ob.getBRPoint().getY() + " nohead lt -1");

            output("set arrow from " + ob.getBRPoint().getX() + ", " + ob.getBRPoint().getY() + " to " +
                    ob.getTRPoint().getX() + ", " + ob.getTRPoint().getY() + " nohead lt -1");

            output("set arrow from " + ob.getTRPoint().getX() + ", " + ob.getTRPoint().getY() + " to " +
                    ob.getTLPoint().getX() + ", " + ob.getTLPoint().getY() + " nohead lt -1");

            output("set arrow from " + ob.getTLPoint().getX() + ", " + ob.getTLPoint().getY() + " to " +
                    ob.getBLPoint().getX() + ", " + ob.getBLPoint().getY() + " nohead lt -1");
        }

        
        for (Base ob : world.getBases())
        {
            int color = 4;
            if (ob.getTeamColor().equalsIgnoreCase("red"))
            {
                color = 1;
            } else
            {
                if (ob.getTeamColor().equalsIgnoreCase("green"))
                {
                    color = 7;
                } else
                {
                    if (ob.getTeamColor().equalsIgnoreCase("blue"))
                    {
                        color = 3;
                    }
                }
            }

            output("set arrow from " + ob.getBLPoint().getX() + ", " + ob.getBLPoint().getY() + " to " +
                    ob.getBRPoint().getX() + ", " + ob.getBRPoint().getY() + " nohead lt "+color);

            output("set arrow from " + ob.getBRPoint().getX() + ", " + ob.getBRPoint().getY() + " to " +
                    ob.getTRPoint().getX() + ", " + ob.getTRPoint().getY() + " nohead lt "+color);

            output("set arrow from " + ob.getTRPoint().getX() + ", " + ob.getTRPoint().getY() + " to " +
                    ob.getTLPoint().getX() + ", " + ob.getTLPoint().getY() + " nohead lt "+color);

            output("set arrow from " + ob.getTLPoint().getX() + ", " + ob.getTLPoint().getY() + " to " +
                    ob.getBLPoint().getX() + ", " + ob.getBLPoint().getY() + " nohead lt "+color);
        }

        for (Flag f : world.getFlags())
        {
            int color = 4;
            if (f.getOwnerColor().equalsIgnoreCase("red"))
            {
                color = 1;
            } else
            {
                if (f.getOwnerColor().equalsIgnoreCase("green"))
                {
                    color = 2;
                } else
                {
                    if (f.getOwnerColor().equalsIgnoreCase("blue"))
                    {
                        color = 3;
                    }
                }
            }
            output("set arrow from " + (f.getLocation().getX()-4) + ", " + (f.getLocation().getY()) + " to " +
                    (f.getLocation().getX()+4) + ", " + (f.getLocation().getY()) + " nohead lt "+color);
            output("set arrow from " + (f.getLocation().getX()) + ", " + (f.getLocation().getY()-4) + " to " +
                    (f.getLocation().getX()) + ", " + (f.getLocation().getY()+4) + " nohead lt "+color);
        }
        
        for(Friend f : world.getFriends())
        {
            int color = 4;
            if (f.getColor().equalsIgnoreCase("red"))
            {
                color = 1;
            } else
            {
                if (f.getColor().equalsIgnoreCase("green"))
                {
                    color = 2;
                } else
                {
                    if (f.getColor().equalsIgnoreCase("blue"))
                    {
                        color = 3;
                    }
                }
            }
            
            output("set arrow from " + (f.getLocation().getX()-2) + ", " + (f.getLocation().getY()) + " to " +
                    (f.getLocation().getX()) + ", " + (f.getLocation().getY()+2) + " nohead lt "+color);
            output("set arrow from " + (f.getLocation().getX()) + ", " + (f.getLocation().getY()+2) + " to " +
                    (f.getLocation().getX()+2) + ", " + (f.getLocation().getY()) + " nohead lt "+color);
            output("set arrow from " + (f.getLocation().getX()+2) + ", " + (f.getLocation().getY()) + " to " +
                    (f.getLocation().getX()) + ", " + (f.getLocation().getY()-2) + " nohead lt "+color);
            output("set arrow from " + (f.getLocation().getX()) + ", " + (f.getLocation().getY()-2) + " to " +
                    (f.getLocation().getX()-2) + ", " + (f.getLocation().getY()) + " nohead lt "+color);
        }
        
        for(Enemy e : world.getEnemies())
        {
            int color = 4;
            if (e.getColor().equalsIgnoreCase("red"))
            {
                color = 1;
            } else
            {
                if (e.getColor().equalsIgnoreCase("green"))
                {
                    color = 2;
                } else
                {
                    if (e.getColor().equalsIgnoreCase("blue"))
                    {
                        color = 3;
                    }
                }
            }
            output("set arrow from " + (e.getLocation().getX()-2) + ", " + (e.getLocation().getY()) + " to " +
                    (e.getLocation().getX()) + ", " + (e.getLocation().getY()+2) + " nohead lt "+color);
            output("set arrow from " + (e.getLocation().getX()) + ", " + (e.getLocation().getY()+2) + " to " +
                    (e.getLocation().getX()+2) + ", " + (e.getLocation().getY()) + " nohead lt "+color);
            output("set arrow from " + (e.getLocation().getX()+2) + ", " + (e.getLocation().getY()) + " to " +
                    (e.getLocation().getX()) + ", " + (e.getLocation().getY()-2) + " nohead lt "+color);
            output("set arrow from " + (e.getLocation().getX()) + ", " + (e.getLocation().getY()-2) + " to " +
                    (e.getLocation().getX()-2) + ", " + (e.getLocation().getY()) + " nohead lt "+color);
            
        }
    }

    public void printLine(Point start, Point end, int color, boolean persists)
    {
       // System.out.println("going to next node");
        if (persists)
        {
            output("set arrow from " + start.getX() + ", " + start.getY() + " to " + end.getX() + ", " + end.getY() + " nohead lt " + color);
        } else
        {
            output("plot '-' with lines");
            output(start.getX() + " " + start.getY() + " " + end.getX() + " " + end.getY());
            output("e");
        }

    }
    
    public void printX(Point point, int color)
    {
       // System.out.println("going to next node");
       output("set arrow from " + (point.getX()-4) + ", " + (point.getY()) + " to " +
                    (point.getX()+4) + ", " + (point.getY()) + " nohead lt "+color);
            output("set arrow from " + (point.getX()) + ", " + (point.getY()-4) + " to " +
                    (point.getX()) + ", " + (point.getY()+4) + " nohead lt "+color);

    }
    
    private void printAnimationData(double delay)
    {
        output("plot '-' with lines");
        output("0 0 0 0");
        output("e");
        output("pause " + plotSpeed);
    }

    public void printNode(Point node, int color)
    {
        output("set data style points");
        output("set pointsize 4.5");
        output("plot '-' with points");
        output(node.getX() + " " + node.getY());
        output("e");
        output("pause " + plotSpeed);
    }

    private void printFooterData()
    {
        output("plot '-' with lines");
        output("0 0 0 0");
        output("e");
    }
}
